/**
 * 重组件懒加载包装器
 *
 * 🎯 核心功能：
 * 1. 对思维导图、流程图、白板等重组件进行懒加载
 * 2. 使用 React.lazy + Suspense 实现代码分割
 * 3. 提供专门的加载占位符
 * 4. 支持错误边界处理
 */

import React, { Suspense } from "react";

/**
 * 思维导图加载占位符
 * 模拟思维导图的基本结构
 */
const MindMapPlaceholder: React.FC<{ width?: number; height?: number }> = ({ width = 900, height = 600 }) => (
  <div
    className="flex items-center justify-center bg-gray-50 border-2 border-dashed border-gray-300 rounded-lg"
    style={{ width, height }}
  >
    <div className="text-center space-y-4">
      <div className="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-500 mx-auto"></div>
      <div className="space-y-2">
        <div className="text-gray-600 font-medium">🧠 思维导图加载中...</div>
        <div className="text-sm text-gray-500">正在加载思维导图组件</div>
      </div>

      {/* 模拟思维导图结构 */}
      <div className="mt-8 space-y-4">
        <div className="flex justify-center">
          <div className="w-24 h-8 bg-blue-200 rounded-full animate-pulse"></div>
        </div>
        <div className="flex justify-center space-x-8">
          <div className="w-20 h-6 bg-green-200 rounded-full animate-pulse"></div>
          <div className="w-20 h-6 bg-purple-200 rounded-full animate-pulse"></div>
          <div className="w-20 h-6 bg-yellow-200 rounded-full animate-pulse"></div>
        </div>
      </div>
    </div>
  </div>
);

/**
 * 流程图加载占位符
 * 模拟流程图的基本结构
 */
const FlowchartPlaceholder: React.FC<{ width?: number; height?: number }> = ({ width = 900, height = 600 }) => (
  <div
    className="flex items-center justify-center bg-gray-50 border-2 border-dashed border-gray-300 rounded-lg"
    style={{ width, height }}
  >
    <div className="text-center space-y-4">
      <div className="animate-spin rounded-full h-12 w-12 border-b-2 border-orange-500 mx-auto"></div>
      <div className="space-y-2">
        <div className="text-gray-600 font-medium">🔶 流程图加载中...</div>
        <div className="text-sm text-gray-500">正在加载流程图组件</div>
      </div>

      {/* 模拟流程图结构 */}
      <div className="mt-8 space-y-4">
        <div className="flex justify-center">
          <div className="w-16 h-10 bg-orange-200 rounded animate-pulse"></div>
        </div>
        <div className="flex justify-center">
          <div className="w-0.5 h-8 bg-gray-300"></div>
        </div>
        <div className="flex justify-center space-x-4">
          <div className="w-16 h-10 bg-blue-200 rounded animate-pulse"></div>
          <div className="w-16 h-10 bg-green-200 rounded animate-pulse"></div>
        </div>
      </div>
    </div>
  </div>
);

/**
 * 白板加载占位符
 * 模拟白板的基本结构
 */
const WhiteboardPlaceholder: React.FC<{ width?: number; height?: number }> = ({ width = 900, height = 600 }) => (
  <div
    className="flex items-center justify-center bg-gray-50 border-2 border-dashed border-gray-300 rounded-lg"
    style={{ width, height }}
  >
    <div className="text-center space-y-4">
      <div className="animate-spin rounded-full h-12 w-12 border-b-2 border-purple-500 mx-auto"></div>
      <div className="space-y-2">
        <div className="text-gray-600 font-medium">🧩 白板加载中...</div>
        <div className="text-sm text-gray-500">正在加载白板组件</div>
      </div>

      {/* 模拟白板工具栏 */}
      <div className="mt-8 space-y-4">
        <div className="flex justify-center space-x-2">
          {[1, 2, 3, 4, 5].map(i => (
            <div key={i} className="w-8 h-8 bg-gray-300 rounded animate-pulse"></div>
          ))}
        </div>
        <div className="flex justify-center space-x-4 mt-6">
          <div className="w-20 h-20 bg-purple-200 rounded-full animate-pulse"></div>
          <div className="w-16 h-24 bg-blue-200 rounded animate-pulse"></div>
          <div className="w-24 h-16 bg-green-200 rounded animate-pulse"></div>
        </div>
      </div>
    </div>
  </div>
);

/**
 * 错误边界组件
 * 处理懒加载组件的加载失败情况
 */
class LazyComponentErrorBoundary extends React.Component<
  { children: React.ReactNode; componentName: string },
  { hasError: boolean; error?: Error }
> {
  constructor(props: { children: React.ReactNode; componentName: string }) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error: Error) {
    return { hasError: true, error };
  }

  componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
    console.error(`懒加载组件错误 [${this.props.componentName}]:`, error, errorInfo);
  }

  render() {
    if (this.state.hasError) {
      return (
        <div className="flex items-center justify-center bg-red-50 border-2 border-red-200 rounded-lg p-8">
          <div className="text-center space-y-2">
            <div className="text-red-600 font-medium">❌ 组件加载失败</div>
            <div className="text-sm text-red-500">{this.props.componentName} 组件无法加载</div>
            <button
              className="mt-4 px-4 py-2 bg-red-100 text-red-700 rounded hover:bg-red-200"
              onClick={() => window.location.reload()}
            >
              刷新页面重试
            </button>
          </div>
        </div>
      );
    }

    return this.props.children;
  }
}

// 使用 React.lazy 进行代码分割
// 注意：这些组件将被打包为独立的 chunk，按需加载

/**
 * 懒加载思维导图组件
 * 使用动态 import 实现代码分割
 */
const LazyMindMapBlockView = React.lazy(() =>
  import("@/components/MindmapBlockView")
    .then(module => {
      console.log("思维导图组件加载成功:", module);
      return {
        default: module.MindMapBlockView
      };
    })
    .catch(error => {
      console.error("思维导图组件加载失败:", error);
      // 返回一个错误占位组件
      return {
        default: () => (
          <div className="p-4 bg-red-50 border border-red-200 rounded">
            <p className="text-red-600">思维导图组件加载失败: {error.message}</p>
          </div>
        )
      };
    })
);

/**
 * 懒加载流程图组件
 */
const LazyFlowchartBlockView = React.lazy(() =>
  import("@/components/FlowchartBlockView")
    .then(module => ({
      default: module.FlowchartBlockView
    }))
    .catch(error => {
      console.error("流程图组件加载失败:", error);
      return {
        default: () => (
          <div className="p-4 bg-red-50 border border-red-200 rounded">
            <p className="text-red-600">流程图组件加载失败</p>
          </div>
        )
      };
    })
);

/**
 * 懒加载白板组件
 */
const LazyWhiteboardBlockView = React.lazy(() =>
  import("@/components/WhiteboardBlockView")
    .then(module => ({
      default: module.WhiteboardBlockView
    }))
    .catch(error => {
      console.error("白板组件加载失败:", error);
      return {
        default: () => (
          <div className="p-4 bg-red-50 border border-red-200 rounded">
            <p className="text-red-600">白板组件加载失败</p>
          </div>
        )
      };
    })
);

/**
 * 懒加载思维导图包装器
 * 提供加载状态和错误处理
 */
export const LazyMindMapWrapper: React.FC<any> = props => {
  const width = props.block?.props?.width || 900;
  const height = props.block?.props?.height || 600;

  return (
    <LazyComponentErrorBoundary componentName="思维导图">
      <Suspense fallback={<MindMapPlaceholder width={width} height={height} />}>
        <LazyMindMapBlockView {...props} />
      </Suspense>
    </LazyComponentErrorBoundary>
  );
};

/**
 * 懒加载流程图包装器
 */
export const LazyFlowchartWrapper: React.FC<any> = props => {
  const width = props.block?.props?.width || 900;
  const height = props.block?.props?.height || 600;

  return (
    <LazyComponentErrorBoundary componentName="流程图">
      <Suspense fallback={<FlowchartPlaceholder width={width} height={height} />}>
        <LazyFlowchartBlockView {...props} />
      </Suspense>
    </LazyComponentErrorBoundary>
  );
};

/**
 * 懒加载白板包装器
 */
export const LazyWhiteboardWrapper: React.FC<any> = props => {
  const width = props.block?.props?.width || 900;
  const height = props.block?.props?.height || 600;

  return (
    <LazyComponentErrorBoundary componentName="白板">
      <Suspense fallback={<WhiteboardPlaceholder width={width} height={height} />}>
        <LazyWhiteboardBlockView {...props} />
      </Suspense>
    </LazyComponentErrorBoundary>
  );
};

/**
 * 通用重组件懒加载工厂函数
 * 可用于包装其他重组件
 */
export function createLazyHeavyComponent<T extends object>(
  importFunction: () => Promise<{ default: React.ComponentType<T> }>,
  PlaceholderComponent: React.ComponentType<any>,
  componentName: string
) {
  const LazyComponent = React.lazy(importFunction);

  return React.forwardRef<any, T>((props, ref) => (
    <LazyComponentErrorBoundary componentName={componentName}>
      <Suspense fallback={<PlaceholderComponent {...props} />}>
        <LazyComponent {...props} ref={ref} />
      </Suspense>
    </LazyComponentErrorBoundary>
  ));
}
